package com.cnswhy.cloud.server.comsumer.consumer.split;

import com.cnswhy.cloud.common.core.entity.constant.CnswhyConstant;
import com.cnswhy.cloud.common.core.exception.BizException;
import com.cnswhy.cloud.common.core.mybatis.conditions.Wraps;
import com.cnswhy.cloud.common.core.utils.SystemClockUtil;
import com.cnswhy.cloud.common.logging.uitls.MDCUtil;
import com.cnswhy.cloud.common.rabbitmq.service.MessageService;
import com.cnswhy.cloud.common.redis.annotation.RedisLock;
import com.cnswhy.cloud.common.redis.model.LockTimeoutStrategy;
import com.cnswhy.cloud.common.redis.service.RedisService;
import com.cnswhy.cloud.server.common.entity.constant.AmqpExchange;
import com.cnswhy.cloud.server.common.entity.enumeration.AccountFlag;
import com.cnswhy.cloud.server.common.entity.enumeration.BusType;
import com.cnswhy.cloud.server.common.entity.enumeration.IotType;
import com.cnswhy.cloud.server.common.entity.mq.IotclOrderSplitMQ;
import com.cnswhy.cloud.server.common.entity.mq.SplitAccountMQ;
import com.cnswhy.cloud.server.comsumer.event.split.IotclOrderSplitEvent;
import com.cnswhy.cloud.server.core.entity.*;
import com.cnswhy.cloud.server.core.service.IotChargingLineTransOrderService;
import com.cnswhy.cloud.server.core.service.IotTerminalInfoService;
import com.cnswhy.cloud.server.core.service.SplitTransRecordService;
import com.cnswhy.cloud.server.core.service.customer.CustomerService;
import com.cnswhy.cloud.server.core.service.merchant.MerchantService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

@Component
@Slf4j
public class IotclOrderSplitConsumer implements IotclOrderSplitEvent {
    @Autowired
    IotChargingLineTransOrderService iotChargingLineTransOrderService;
    @Autowired
    IotTerminalInfoService iotTerminalInfoService;
    @Autowired
    CustomerService customerService;
    @Autowired
    MerchantService merchantService;
    @Autowired
    RedisService redisService;
    @Autowired
    SplitTransRecordService splitTransRecordService;
    @Autowired
    MessageService messageService;
    @Override
    public void split(IotclOrderSplitMQ iotclOrderSplitMQ) throws BizException {
        if(iotclOrderSplitMQ.getIotChargingLineOrderId() == null){
            log.error("充电线订单id为空");
            return;
        }
        log.info("充电线订单分账:{}",iotclOrderSplitMQ.getIotChargingLineOrderId());
        if(splitFlag(iotclOrderSplitMQ.getIotChargingLineOrderId())){
            log.error("充电线分账已存在:{}",iotclOrderSplitMQ.getIotChargingLineOrderId());
            return;
        }
        IotChargingLineTransOrder iotChargingLineTransOrder = iotChargingLineTransOrderService.getById(iotclOrderSplitMQ.getIotChargingLineOrderId());
        if(iotChargingLineTransOrder == null){
            log.error("充电线订单未找到:{}", iotclOrderSplitMQ.getIotChargingLineOrderId());
            return;
        }
        //查询终端设备
        IotTerminalInfo iotTerminalInfo = iotTerminalInfoService.getOne(Wraps.<IotTerminalInfo>lbQ().eq(IotTerminalInfo::getTerminalId,iotChargingLineTransOrder.getTerminalId()).eq(IotTerminalInfo::getIotType, IotType.IOT_CHARG_LINE));
        if(iotTerminalInfo == null){
            log.error("无效终端号:{}", iotChargingLineTransOrder.getTerminalId());
            return;
        }
        log.info("订单号:{} 订单金额:{} 终端号:{} 客户id:{} 商户ID:{} 分账比例:{}",
                iotChargingLineTransOrder.getOrderId(),
                iotChargingLineTransOrder.getTransAmt(),
                iotChargingLineTransOrder.getTerminalId(),
                iotTerminalInfo.getCustomerId(),
                iotTerminalInfo.getMerchantId(),
                iotTerminalInfo.getSplit()
                );
        //查找终端服务商
        Customer customer = customerService.getById(iotTerminalInfo.getCustomerId());
        if(customer == null){
            log.error("终端服务商未找到:id={}", iotTerminalInfo.getCustomerId());
            return;
        }
        //查找终端商家
        Merchant merchant = merchantService.getById(iotTerminalInfo.getMerchantId());
        if(merchant == null){
            log.info("终端商家未找到:id={}",iotTerminalInfo.getMerchantId());
            return;
        }
        int level = 0;
        Long split = Long.valueOf(100);
        if(merchant.getIsPublic() == 1 && !merchant.getCustomerId().equals(customer.getId())){
            //公海商家，要分账
            Customer merchantCustomer = customerService.getById(merchant.getCustomerId());
            SplitTransRecord splitTransRecord = addSPlitTransRecord(iotChargingLineTransOrder,customer,merchantCustomer,iotTerminalInfo.getSplit(), ++ level);
            if(splitTransRecord != null){
                SplitAccountMQ splitAccountMQ = SplitAccountMQ.builder().splitTransRecordId(splitTransRecord.getId()).build();
                splitAccountMQ.setTraceId(MDCUtil.getTraceId());
                messageService.sendQueueByObject(AmqpExchange.SPLIT_ACCOUNT_MESSAGE, splitAccountMQ);
            }
            split = split - iotTerminalInfo.getSplit();
        }
        SplitTransRecord splitTransRecord = addSPlitTransRecord(iotChargingLineTransOrder,customer,customer,split, ++ level);
        if(splitTransRecord != null){
            SplitAccountMQ splitAccountMQ = SplitAccountMQ.builder().splitTransRecordId(splitTransRecord.getId()).build();
            splitAccountMQ.setTraceId(MDCUtil.getTraceId());
            messageService.sendQueueByObject(AmqpExchange.SPLIT_ACCOUNT_MESSAGE, splitAccountMQ);
        }
        log.info("充电线订单分账:{} 分账",iotclOrderSplitMQ.getIotChargingLineOrderId());
    }
    @RedisLock(name = "splitFlag", waitTime = 10,leaseTime = 60,keys = {"#iotChargingLineOrderId"},lockTimeoutStrategy = LockTimeoutStrategy.FAIL_FAST)
    private boolean splitFlag(Long iotChargingLineOrderId){
        String abc = (String)redisService.hget("IotclOrderSplitConsumer" , iotChargingLineOrderId.toString());
        if (StringUtils.isNotBlank(abc)) {
            return true;
        }
        redisService.hset("IotclOrderSplitConsumer" , iotChargingLineOrderId.toString(), iotChargingLineOrderId.toString(), CnswhyConstant.DAY_SECONDS / 24);
        return false;
    }



    private SplitTransRecord addSPlitTransRecord(IotChargingLineTransOrder iotChargingLineTransOrder, Customer customer,Customer merchantCustomer, Long split, int level){
        //Customer customer = customerService.getById(promoterId);

        BigDecimal feeAmt = BigDecimal.valueOf(iotChargingLineTransOrder.getTransAmt()).multiply(BigDecimal.valueOf(split.doubleValue() / 100)).setScale(0, BigDecimal.ROUND_HALF_UP);
        Long splitAmt = feeAmt.longValue();
        if(splitAmt.compareTo(0L) <= 0){
            return null;
        }
        SplitTransRecord splitTransRecord1 = splitTransRecordService.getOne(
                Wraps.<SplitTransRecord>lbQ().eq(SplitTransRecord::getOrderId, iotChargingLineTransOrder.getOrderId())
                        .eq(SplitTransRecord::getSplitCustomerId, merchantCustomer.getId())
        );
        if(splitTransRecord1 != null){
            log.error("分账记录已存在");
            return null;
        }
        SplitTransRecord splitTransRecord = SplitTransRecord.builder()
                .busType(BusType.IOT_CHARG_LINE)
                .customerId(customer.getId())
                .orderId(iotChargingLineTransOrder.getOrderId())
                .transAmt(iotChargingLineTransOrder.getTransAmt())
                .splitLevel(level)
                .mobile(customer.getLoginName())
                .settDate(SystemClockUtil.getSettDateyyyyMMdd())
                .promoterMobile(merchantCustomer.getLoginName())
                .splitFee(splitAmt)
                .splitExternFee(0L)
                .splitAmt(splitAmt)
                .splitCustomerId(merchantCustomer.getId())
                .promoterName(merchantCustomer.getVerifyName())
                .custName(customer.getVerifyName())
                .accountFlag(AccountFlag.NONE.getVal()).build();
        splitTransRecordService.save(splitTransRecord);
        return splitTransRecord;
    }
}
